home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Libraries / BlobMgr / Demo Folder / Hang.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-21  |  5.3 KB  |  275 lines  |  [TEXT/KAHL]

  1. /*
  2.  * Blob Manager Demonstration:    Hangman - the classic game
  3.  *
  4.  * This module is a little unusual in that it doesn't use BlobClick.
  5.  * The user chooses letters simply by clicking on them and the
  6.  * scenario in effect drags the letters to the receptors itself.
  7.  *
  8.  * 26 July 1986        Paul DuBois
  9.  */
  10.  
  11. # include    "TransSkel.h"
  12.  
  13. # include    "BlobMgr.h"
  14. # include    "BlobDemo.h"
  15.  
  16.  
  17. # define    hWord        10    /* horizontal position of word to find */
  18. # define    vWord        5    /* vertical position */
  19. # define    hLetters    10    /* location of letter pool */
  20. # define    vLetters    35
  21. # define    vMesg        85
  22. # define    vMan        75
  23.  
  24. # define    letterSize    18    /* size of letter blobs */
  25. # define    letterGap    2    /* gap between blobs */
  26.  
  27.  
  28. static WindowPtr        wind;
  29. static ControlHandle    button;
  30.  
  31.  
  32. static BlobSetHandle    letters = nil;        /* donor blobs */
  33. static BlobSetHandle    word = nil;            /* word to be found */
  34.  
  35. static Boolean            pause;
  36. static short            wrongMoves;
  37. static short            hMid;
  38. static Str255            statusStr = "\p";
  39.     
  40.  
  41. static void
  42. StatusMesg (StringPtr s)
  43. {
  44. Rect    r;
  45.  
  46.     SetRect (&r, hMid - 45, vMesg, hMid + 45, vMesg + 20);
  47.     TextBox (s+1, (long) s[0], &r, teJustCenter);
  48.     StrCpy (statusStr, s);
  49. }
  50.  
  51.  
  52. /*
  53.  * Make donor blobs.
  54.  */
  55.  
  56. static void
  57. MakeDonors (void)
  58. {
  59. short    i, j, h, v;
  60.  
  61.     letters = NewBlobSet ();
  62.     v = vLetters;
  63.     for (i = 0; i < 2; ++i)
  64.     {
  65.         h = hLetters;
  66.         for (j = 0; j < 13; ++j)
  67.         {
  68.             (void) MakeCharBlob (letters, true, infiniteGlue, false,
  69.                                 h, v, i * 13 + j + 'a');
  70.             h += letterSize + letterGap;
  71.         }
  72.         v += letterSize + letterGap;
  73.     }
  74. }
  75.  
  76.  
  77. /*
  78.  * Generate a new problem to solve:  get a word from the word picker.
  79.  */
  80.  
  81. static void
  82. GenerateProblem (void)
  83. {
  84. BlobHandle    b;
  85. char        *s;
  86. short        i;
  87. short        h;
  88.  
  89.     /* get rid of any old word blob set */
  90.  
  91.     if (word != nil)
  92.     {
  93.         HideBlobSet (word);
  94.         DisposeBlobSet (word);
  95.     }
  96.     word = NewBlobSet ();
  97.     s = (char *) PickWord ();
  98.  
  99.     /* create new blob set, attach match information */
  100.  
  101.     h = hMid - (s[0] * (letterSize + letterGap) - letterGap) / 2;
  102.     for (i = 1; i <= s[0]; ++i)
  103.     {
  104.         b =  MakeCharBlob (word, true, 0, true, h, vWord, ' ');
  105.         NewBlobMatch (GetBlobHandle (letters, s[i] - 'a'), b);
  106.         h += letterSize + letterGap;
  107.     }
  108. }
  109.  
  110.  
  111. static void
  112. OneDrawMan (short h, short v)    /* h,v is point at top of man's head */
  113. {
  114. Rect        r;
  115. PenState    ps;
  116.  
  117.     if (wrongMoves == 0)        /* erase man */
  118.     {
  119.         wrongMoves = 7;            /* draw entire man in bit-clear mode */
  120.         GetPenState (&ps);
  121.         PenMode (patBic);
  122.         OneDrawMan (h, v);
  123.         wrongMoves = 0;
  124.         SetPenState (&ps);
  125.         return;
  126.     }
  127.     SetRect (&r, h - 6, v, h + 7, v + 16);
  128.     FrameOval (&r);
  129.     if (wrongMoves == 1) return;
  130.     MoveTo (h, v + 16);
  131.     LineTo (h, v + 20);
  132.     if (wrongMoves == 2) return;
  133.     LineTo (h - 16, v + 32);
  134.     if (wrongMoves == 3) return;
  135.     MoveTo (h, v + 20);
  136.     LineTo (h + 16, v + 32);
  137.     if (wrongMoves == 4) return;
  138.     MoveTo (h, v + 20);
  139.     LineTo (h, v + 40);
  140.     if (wrongMoves == 5) return;
  141.     LineTo (h - 16, v + 56);
  142.     if (wrongMoves == 6) return;
  143.     MoveTo (h, v + 40);
  144.     LineTo (h + 16, v + 56);
  145. }
  146.  
  147.  
  148. static void
  149. DrawMan (void)
  150. {
  151.     OneDrawMan (hMid - 80, vMan);
  152.     OneDrawMan (hMid + 80, vMan);
  153. }
  154.  
  155.  
  156. static void
  157. NextProblem (void)
  158. {
  159.     StatusMesg ("\p");            /* clear message */
  160.     wrongMoves = 0;
  161.     DrawMan ();
  162.     HiliteControl (button, dimHilite);
  163.     if (word != nil)
  164.         ZUnglueGlobSet (word);        /* detach all letters */
  165.     HiliteBlobSet (letters, inFullBlob, normalDraw);
  166.     GenerateProblem ();
  167.     pause = false;
  168.     ValidRect (&wind->portRect);
  169. }
  170.  
  171.  
  172. /*
  173.  * Either the word was discovered or the man hung.    Set up to pause
  174.  * until the Resume button is hit.
  175.  */
  176.  
  177. static void
  178. Pause (StringPtr msg)
  179. {
  180.     StatusMesg (msg);
  181.     HiliteControl (button, normalHilite);    /* enable button */
  182.     pause = true;
  183. }
  184.  
  185.  
  186. static pascal void
  187. Mouse (Point pt, long t, short mods)
  188. {
  189. BlobHandle        b, r;
  190. ControlHandle    ctl;
  191. short            matches = 0;
  192.  
  193.     if (FindControl (pt, wind, &ctl))
  194.     {
  195.         if (TrackControl (ctl, pt, nil))    /* button hit? */
  196.         {
  197.             NextProblem ();
  198.         }
  199.     }
  200.     else if (!pause && FindBlob (pt, letters, &b) != 0)
  201.     {
  202.         if (!BTrackMouse (b, pt, inDragBlob))
  203.             return;
  204.         for (r = FirstBlob (word); r != nil; r = NextBlob (r))
  205.         {
  206.             if (b == FirstBMatch (r))
  207.             {
  208.                 ZGlueGlob (b, r);
  209.                 ++matches;
  210.             }
  211.         }
  212.         HiliteBlob (b, inFullBlob, dimDraw);    /* force used letter dim */
  213.         if (matches > 0)    /* letter correct */
  214.         {
  215.             if (BlobSetQuiet (word))    /* find answer? */
  216.                 Pause ("\pCorrect");
  217.         }
  218.         else                /* letter incorrect */
  219.         {
  220.             ++wrongMoves;
  221.             DrawMan ();
  222.             if (wrongMoves == 7)
  223.             {
  224.                 Pause ("\pYou Lose");
  225.                 for (r = FirstBlob (word); r != nil; r = NextBlob (r))
  226.                 {
  227.                     if (BGlob (r) == nil)    /* show not-found letters */
  228.                         ZGlueGlob (FirstBMatch (r), r);
  229.                 }
  230.             }
  231.         }
  232.     }
  233. }
  234.  
  235.  
  236. static pascal void
  237. Update (Boolean resized)
  238. {
  239.     DrawBlobSet (word);
  240.     DrawBlobSet (letters);
  241.     StatusMesg (statusStr);
  242.     DrawControls (wind);
  243.     DrawMan ();
  244. }
  245.  
  246.  
  247. void
  248. HangInit (void)
  249. {
  250. Rect    r;
  251. short    i;
  252.  
  253.     SkelWindow (wind = GetDemoWind (hangWindRes),
  254.                 Mouse,            /* mouse clicks */
  255.                 nil,            /* key clicks */
  256.                 Update,            /* updates */
  257.                 nil,            /* activate/deactivate events */
  258.                 nil,            /* close window */
  259.                 DoWClobber,        /* dispose of window */
  260.                 nil,            /* idle proc */
  261.                 false);            /* irrelevant, since no idle proc */
  262.  
  263.     hMid = wind->portRect.right / 2;
  264.     SetRect (&r, 0, 0, 80, 20);
  265.     OffsetRect (&r, hMid - 40, wind->portRect.bottom - 25);
  266.     button = NewControl (wind, &r, "\pNext", true, 0, 0, 0,
  267.                             pushButProc, 0L);
  268.  
  269.     SetCharBlobSize (letterSize);
  270.     MakeDonors ();
  271.     NextProblem ();
  272.  
  273.     MakeFrontWind (wind);
  274. }
  275.